-
Notifications
You must be signed in to change notification settings - Fork 13.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(datetime): scroll to newly selected date when value changes #27806
Conversation
Run & review this pull request in StackBlitz Codeflow. |
…but seems to work)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still in progress of manually testing. Dropping some early suggestions for changes.
* Animate smoothly to the forced month. This will also update | ||
* workingParts and correct the surrounding months for us. | ||
*/ | ||
const targetMonthIsEarlier = isBefore(targetValue, workingParts); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Threading:
My understanding of the original issue is that asynchronously setting the datetime on load does not update the view. So if the datetime is going to be set either on load or shortly after load, will users even see this scrolling animation? For example, if a datetime in a modal has its value set as the modal opens, the scrolling would either happen on screen or as the modal transitions in.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is mainly to mirror native behavior, which animates on both MUI and native iOS: https://github.com/ionic-team/ionic-framework-design-documents/blob/main/projects/ionic-framework/components/datetime/0003-datetime-async-value.md#references
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@liamdebeasi Before I get too deep in bug fixes here, I wanted to check whether you still had any concerns with moving forward with the animation. I can understand wanting to avoid making datetime even more complex, and deciding to scrap the animation part would make fixing things up here easier, but there are a few reasons why I still feel we should go through with it:
- The animation matches native behavior, as mentioned above.
- The datetime won't always be hidden when the value is updated async. While that will definitely be our recommendation (see docs(datetime): add best practices for setting value async ionic-docs#3053), we should avoid glitchy-looking behavior when it isn't the dev's desired pattern. For example, an app could have a dropdown with appointments, and the datetime's value updates to reflect which one you've selected.
- The animation is something we already decided on in the design doc, and I would rather commit to that than constantly be rethinking our decisions. This isn't a case where we missed something that dramatically changes the scope; we already recognized that the animation will be difficult, and decided to proceed anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree we shouldn't omit the animation just because it is challenging. But I'd also like us to keep in mind that the primary objective is to update the UI, with the animation being a secondary goal. This behavior is similar to #23560 where it is closer to the spec, but it's not critical functionality.
I'm not advocating for removing this, but I do want to make sure we are being cautious. If you recall the old IntersectionObserver implementation in datetime, that consumed a lot of our time before we eventually abandoned that approach in favor of a scroll listener.
|
||
// Open month/year picker | ||
await monthYearButton.click(); | ||
await page.waitForChanges(); | ||
|
||
// Select October 2021 | ||
// The year will automatically switch to 2021 when selecting 10 | ||
await monthColumn.locator('.picker-item[data-value="10"]').click(); | ||
await ionChange.next(); | ||
|
||
// Close month/year picker | ||
await monthYearButton.click(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These parts aren't needed anymore because changing the value already jumps to the new month.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work so far! I found one edge case, though the rest of this is working well.
const didChangeMonth = month !== workingParts.month || year !== workingParts.year; | ||
const bodyIsVisible = el.classList.contains('datetime-ready'); | ||
const { isGridStyle, showMonthAndYear } = this; | ||
if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you set datetime to a time it still scrolls to another month and then abruptly resets to the selected month.
Example:
<ion-datetime value="2022-02-22T16:30:00"></ion-datetime>
<script>
setTimeout(() => {
datetime.value = '16:30';
}, 2000);
</script>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I fixed the wonky scrolling in fbf2f9c. The datetime now errors out if you do this, but it looks like this case (setting the value to just a time when the presentation
is something other than just time
) was never supported; I'm able to trigger the same error on main
after messing with it a bit. (Screencast below.) I'm thinking it would be good to add a warning for this improper usage in a separate ticket. Thoughts?
2023-08-08.11-12-18.mp4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ticket created: https://ionic-cloud.atlassian.net/browse/FW-4996
@@ -206,6 +206,10 @@ export class DatetimeButton implements ComponentInterface { | |||
*/ | |||
const parsedDatetimes = parseDate(parsedValues.length > 0 ? parsedValues : [getToday()]); | |||
|
|||
if (!parsedDatetimes) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unsure if this is a bug, but if I open the month/year picker as the view datetime begins to animate, the animation gets cancelled and the view never updates to the new value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm actually seeing it update; maybe I'm just not doing it quickly enough? (Screencast below.) Even if there is a specific timing that borks it, though, I'm not too worried as long as the highlighted date is correct once you do scroll to it. Seems like a small edge case that could be addressed separately.
2023-08-16.14-18-57.mp4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I had outdated code as I can no longer repro the issue I mentioned. However, another bug exists:
Switching to the month/year picker as the animation starts seems to break date selection altogether.
datetime-break.mov
Tested on Chrome 116. I added the following code to datetime/test/display/index.html
to get the datetime to update async:
setTimeout(() => {
datetime.value = '2023-10-23T16:30'
}, 2000);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm able to trigger that on main
as well, using the next/prev month buttons. The animation goes through the same methods, so it's the same bug. Thoughts on addressing it separately?
2023-08-18.14-17-38.mp4
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that works for me 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ticket created: https://ionic-cloud.atlassian.net/browse/FW-4997
Also thoughts on getting a dev build and getting the community to test? |
Dev build posted in the original issue 👍 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work!
Let's do a couple things before merging:
- Rebase this off
feature-7.4
since we want to get this into a feature release. - Wait a couple more days to give devs time to provide feedback re: the dev build. If there's no response by Wednesday I think it's fine to merge. (That way we give them a full week to test)
I'm waiting on @sean-perkins's review anyway 👀 Definitely think this is worth getting an extra pair of eyes on. |
Any ETA on when this fix will be released? This bug is currently blocking us from releasing an app. |
As noted in #26391 (comment), this fix will be available in an upcoming minor release of Ionic. |
Was this feature ever released? We are experiencing the same problem. Thank you! |
Ok, I found a workaround using these instructions. Using I think it would make a lot of sense to reset automatically in case popover/modal is closed / reopened. |
This feature was released in Ionic 7.4.0: https://ionic.io/blog/announcing-ionic-7-4 |
Issue number: Resolves #26391
What is the current behavior?
When updating the
value
programmatically on anion-datetime
after it has already been created:What is the new behavior?
parseDate
util has also had its type signatures updated to account for returningundefined
when the date string is improperly formatted. This was missed when the util was refactored to support multiple date selection.Does this introduce a breaking change?
Other information
processValue()
. This covers both wheel and grid datetimes.activePartsClone
as a whole was also removed. It was added in fix(datetime): update active calendar display when value changes #24244 to enable changingactiveParts
without triggering a rerender (and thus jumping to the new value) but since we now want to do that jump, the clone is no longer needed.